/*
 * staticObject.cpp
 *
 *  Created on: 17.05.2009
 *      Author: Christian Stupp
 */

#include "../include/staticObject.h"

std::map<std::string, std::string> oal::staticObject::configuration;

struct HTMLReplace {
	string match;
	string replace;
} codes[] = {
	{"&", "&amp;"},
	{"<", "&lt;"},
	{">", "&gt;"}
};

string oal::staticObject::filetime(string filename) {
string result="0";
	struct stat attribut;
	struct tm * timeinfo;
	char buffer [80];

	if(stat(filename.c_str(),&attribut) != -1) {
//		if(attribut.st_mode & S_IFREG) {
			timeinfo = localtime ( &attribut.st_mtime );

			strftime (buffer,80,"%d-%m-%Y",timeinfo);
//			puts (buffer);
			result = trim(buffer);
//			result=trim(&attribut.st_mtime);
//		}
	}
return(result);
}

string oal::staticObject::isLink(string path) {
string result="";
	files *file = new files(path,"r");
	if(file->isFile()) {
		char *buf;
		buf = (char *)malloc(1024 * sizeof(char));
#ifndef _WIN32
		int len=-1;
		if( (len = readlink(path.c_str(),buf,1024)) != -1) {
			result.append(buf,len);
		} else {
			result="file";
		}
#endif
		delete buf;
	}
return(result);
}

string oal::staticObject::htmlEncode( const string& s ) {
string rs = s;

// Replace each matching token in turn
for ( size_t i = 0; i < array_length( codes ); i++ ) {
	// Find the first match
	const string& match = codes[i].match;
	const string& repl = codes[i].replace;
	string::size_type start = rs.find_first_of( match );

	// Replace all matches
	while ( start != string::npos ) {
		rs.replace( start, match.size(), repl );
		// Be sure to jump forward by the replacement length
		start = rs.find_first_of( match, start + repl.size() );
	}
}
return rs;
}
oal::staticObject::staticObject() {
	// TODO Auto-generated constructor stub
}

oal::staticObject::~staticObject() {
	// TODO Auto-generated destructor stub
//	configuration.clear();
}

bool oal::staticObject::isSpace(int in) {
bool result=false;
	if (in == -1 || in == 9 || in == 10 || in == 32 || in == 13 || in == 0) {
		result = true;
	} else{
		result = false;
	}
	return result;
}

/**
 * Trimms a string from the end from tabs
 * spaces and neewline
 *
 * @param	string	untrimmed string
 *
 * @return	string	rigth trimmed string
 */
std::string oal::staticObject::rtrim(std::string rtrim_temp) {
    int i=0;
    int foundin = -1;
    bool found=false;
    for(i=rtrim_temp.length()-1;i>=0;--i) {
        if(isSpace(rtrim_temp[i]) && !found) {
            foundin = i;
        } else {
            found=true;
        }
    }
    if(foundin>=1) {
        rtrim_temp=rtrim_temp.substr(0,foundin);
    }
    return(rtrim_temp);
}

/**
 * Trimms a string from the beginning from tabs
 * spaces and neewline
 *
 * @param	string	untrimmed string
 *
 * @return	string	left trimmed string
 */
std::string oal::staticObject::ltrim(std::string ltrim_temp) {
    int i=0;
    int foundin = -1;
    bool found=false;
    for(i=0;i<(int)ltrim_temp.length();++i) {
        if(isSpace(ltrim_temp[i]) && !found) {
            foundin = i+1;
        } else {
            found=true;
        }
    }
    if(foundin>=1) {
        ltrim_temp=ltrim_temp.substr(foundin,ltrim_temp.length());
    }
    return(ltrim_temp);
}

/**
 * Trimms a string from the end and the beginning from tabs
 * spaces and neewline
 *
 * @param	string	untrimmed string
 *
 * @return	string	trimmed string
 */
std::string oal::staticObject::trim(std::string data) {
	return rtrim(ltrim(data));
}

/**
 * makes the char to uppercase char
 *
 * @param	string	content to make uppercase
 *
 * @return	string	uppercase string
 */
char oal::staticObject::charToUpper(char newChar) {
	if (97<=newChar&&newChar<=122) {
		newChar-=32;
	}
	return newChar;
}

/**
 * makes the char to lowercase char
 *
 * @param	string	content to make lowercase
 *
 * @return	string	lowercase string
 */
char oal::staticObject::charToLower(char newChar) {
	if (65<=newChar&&newChar<=90) {
		newChar+=32;
	}
    return newChar;
}


/**
 * makes the string to uppercase string
 *
 * @param	string	content to make uppercase
 *
 * @return	string	uppercase string
 */
std::string oal::staticObject::stringToUpper(std::string newString) {
	int leng=newString.length();
	for(int i=0; i<leng; i++) {
		newString[i] = charToUpper(newString[i]);
	}
	return newString;
}

/**
 * makes the string to lowercase string
 *
 * @param	string	content to make lowercase
 *
 * @return	string	lowercase string
 */
std::string oal::staticObject::stringToLower(std::string newString) {
	int leng=newString.length();
	for(int i=0; i<leng; i++) {
		newString[i] = charToLower(newString[i]);
	}
    return newString;
}

/**
 * Explode a map with the given seperator
 *
 * @param	string	seperator to explode
 * @param	map		map to explode with seperator
 *
 * @return	string	string seperated by seperator
 */
std::map<std::string,std::string> oal::staticObject::explode(std::string sep, std::string value, std::string sep2) {
	std::map<std::string,std::string> empty;
	value = value + sep;
	int pos=0;
	while((pos = value.find(sep)) > -1) {
		std::string part = value.substr(0,pos);
		int pos2 = part.find(sep2);
		if(pos2 > 0) {
			empty[part.substr(0,pos2)] = part.substr(pos2+1);
		}
		value = value.substr(pos+1);
	}
	return empty;
}

/**
 * Explode a map with the gieven seperator
 *
 * @param	string	seperator to explode
 * @param	map		map to explode with seperator
 *
 * @return	string	string seperated by seperator
 */
std::vector<std::string> oal::staticObject::explodeInt(std::string sep, std::string value, int count) {
	std::vector<std::string> empty;
	value = value + sep;
	int pos=0;
	int found = 0;
	while((pos = value.find(sep)) > -1) {
		std::string part = value.substr(0,pos);
		found++;
		if(count != -1 && found >= count) {
//			cout << "p"<<part << endl;
//			cout << "v"<< value << endl;
			empty.push_back(value.substr(0,value.length()-sep.length()));
			// value = value.substr(pos+sep.length());
			break;
		} else {
			empty.push_back(part);
			value = value.substr(pos+sep.length());
//			cout << "p"<<part << endl;
//			cout << "v"<< value << endl;
		}
	}
	return empty;
}

/**
 * Implode a map with the gieven seperator
 *
 * @param	string	seperator to explode
 * @param	map		map to explode with seperator
 *
 * @return	string	string seperated by the given seperator
 */
std::string oal::staticObject::implode(std::string sep, std::map<std::string,std::string> value) {
std::string result="";
	std::map<std::string,std::string>::iterator iterator;
	for(
		iterator = value.begin();
		iterator != value.end();
		iterator++
	) {
		result += iterator->first + "=" + iterator->second + ",";
	}
	result = result.substr(0,result.length()-1);
	return result;
}

/**
 * Replace a string with another string
 *
 * @param	string	searching string to replace
 * @param	string	replacement string
 * @param	string	content to replace
 */
std::string oal::staticObject::stringReplace(std::string needle, std::string  replace, std::string content) {
	int pos = content.find(needle);
	while(pos >= 0) {
		content.replace(pos,needle.length(), replace);
		pos = content.find(needle);
	}
	return content;
}

/**
 * Gets a part of the file content
 *
 * @param	*string	file content to search
 * @param	string	first needle we search for, can
 * 					not be empty
 * @param	string	second needle we search for, can
 * 					not be empty
 * @param	string	string to search for the beginning position,
 * 					can be empty than search from position 0
 *
 * @return	string	found string between the needle, can be empty
 * 					if nothing found
 */
std::string oal::staticObject::searchInContentFor(
	std::string *content,
	std::string firstNeedle,
	std::string secondNeedle,
	std::string firstPosString
) {
	std::string result = "";
	int pos = (*content).find(firstPosString);
	int firstPos = (*content).find(firstNeedle, pos) + firstNeedle.length();
	int secondPos = (*content).find(secondNeedle, pos);
	if(firstPos>=0 && secondPos>0 && firstPos<secondPos) {
		result = trim((*content).substr(firstPos,secondPos-firstPos));
	}
	return result;
}


/**
 * Makes an time struct (tm) from an referenz date
 *
 * @param	string	referenz date
 * @param	string	option de,en
 *
 * @return	string	tm time struct
 */
#include<iostream>
tm oal::staticObject::makeTimeStruct(std::string datum, std::string art) {
 struct tm tmback;
  datum +="000000000000";
  if(art=="de") {
   tmback.tm_mday = atoi(datum.substr(0,2).c_str());
   tmback.tm_mon = (atoi(datum.substr(3,2).c_str()) - 1);
   tmback.tm_year = (atoi(datum.substr(6,4).c_str()) - 1900);
  } else {
   tmback.tm_year = (atoi(datum.substr(0,4).c_str()) - 1900);
   tmback.tm_mon = (atoi(datum.substr(5,2).c_str()) - 1);
   tmback.tm_mday = atoi(datum.substr(8,2).c_str());
  }
  tmback.tm_hour= atoi(datum.substr(11,2).c_str());
  tmback.tm_min= atoi(datum.substr(14,2).c_str());
  tmback.tm_sec = atoi(datum.substr(17,2).c_str());
  tmback.tm_isdst = 0;
 return(tmback);
}

/**
 * Gets an unix timestamp
 *
 * @param	string	referenz for timestamp
 */
std::string oal::staticObject::timestamp(std::string referenz) {
	std::string result="";
	char buffer[12];
	if(referenz.empty()) {
		time_t tnow;
		time(&tnow);
//		tm *tmnow = localtime(&tnow);
		sprintf(buffer,"%ld\n",tnow);
	} else {
		time_t tnow;
		struct tm tnow2;
		tnow2 = oal::staticObject::makeTimeStruct(referenz);
		mktime(&tnow2);
		tnow = mktime(&tnow2);
		sprintf(buffer,"%ld\n",tnow);
	}
	result = trim(buffer);
	return(result);
}


/**
 * Loads the whole content from the given filename.
 *
 * @param	string	full path of the file to read
 *
 * @return	string	content of the file
 */
std::string oal::staticObject::loadFromFile(std::string fileName) {
	std::string result;
	files *file = new files(fileName,"r");
	if (file->isFile()) {
		result = file->getContent();
	}
	delete file;
	return result;
}

/**
 * Saves the given content in the given file. if an file is exists it will be
 * override with the new content.
 *
 * @param	string	filename to save
 * @param	string	content to save in the given filename
 */
bool oal::staticObject::saveToFile(std::string fileName, std::string content) {
	bool result="";
	files *file = new files(fileName,"w");
	result = file->putContent(content);
	delete file;
	return result;
}

/**
 * Loads the configuration file into the object. this can acccess over
 * the static variable configuration it is a string,string map
 * use configuration[key] to get the value
 *
 * @param	string	path to configuration
 * @param	string	linebreak default is \n
 * @param	string	seperator default is :
 *
 * @return	bool	true if configuration is loaded,
 * 					false otherwise
 */
bool oal::staticObject::parseConfiguration(std::string fileName, std::string linebreak,std::string seperator) {
	files *file = new files(fileName,"r");
	bool result = false;
	if(file->isFile()) {
		std::string content = file->getContent();
		int pos = -1, lastPos = 0;
		while( (pos = content.find(linebreak, pos+1)) > -1) {
			std::string line = content.substr(lastPos, (pos - lastPos));
			int pos2 = line.find(seperator);
			if(pos2>1 && line[0] != '#') {
				configuration[trim(line.substr(0,pos2))] = trim(line.substr(pos2+1));
			}
			lastPos = pos+1;
			result = true;
		}
	}
	delete file;
	return result;
}

/**
 * Gets the given string into an vector. The list of options
 * can be set like the options in a linux programm
 *
 * @param	string	options to put in vector<string>
 *
 * @return	vector<string>	options
 */
std::vector<std::string> oal::staticObject::getOptionFromString(std::string options, int count) {
std::vector<std::string> optionList;
	options = options + " ";
	cout << options << endl;
	int pos=0,co=0;
	while( (pos = options.find(" ")) > 0) {
		std::string newOption = options.substr(0,6);
		if(newOption == "EOF==>") {
			options = options.substr(6);
			break;
		}
		if(newOption[0] == '"' || newOption[0] == '\'') {
			int newPos = options.find(newOption[0],1);
			newOption = options.substr(1,newPos-1);
			options = options.substr(newPos+2);
		} else {
			newOption = options.substr(0,pos);
			options = options.substr(pos+1);
		}
		cout << newOption << endl;
		optionList.push_back(newOption);

		// if(co>100) exit(0); else co++;
		if(co >= count) {
			break;
		}
	}
	if(!options.empty()) {
		optionList.push_back(options);
	}
	return optionList;
}

